package cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ClientSideImageMap;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.apache.wicket.request.resource.ResourceReference;

import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.MusicLibrarySession;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.AlbumFormPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.ArtistFormPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.FormSubmittedEvent;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.GenreFormPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.LoginPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.SearchForm;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.SongFormPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.images.ImageAnchor;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.search.SearchPage;

/**
 * Abstract web page that serves as a common parent for all pages.
 * 
 * @author Maros Kucbel
 * @date 2012-11-16T23:53:40+0100
 */
public abstract class AbstractMusicLibraryPage extends WebPage {

    /**
     * Constructor.
     */
    public AbstractMusicLibraryPage() {
        this(new PageParameters());
    }
    
    /**
     * Constructor
     * @param pageParameters Parameters for page initialization.
     */
    public AbstractMusicLibraryPage(final PageParameters pageParameters) {
        super(pageParameters);
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        response.render(CssHeaderItem.forReference(new CssResourceReference(AbstractMusicLibraryPage.class, "main.css")));
        super.renderHead(response);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        this.initComponents();
    }
    
    private void initComponents() {
        final String pageTitleKey = String.format("%1$s.pageTitle", this.getClass().getSimpleName());
        final IModel<String> pageTitle = new StringResourceModel(pageTitleKey, this, null);
        this.add(new Label("pageTitle", pageTitle));
        Link<Void> homePageLink = new BookmarkablePageLink(ComponentIDs.HOME_PAGE_LINK, SearchPage.class);

        this.add(new SearchForm(ComponentIDs.SEARCH_FORM_PANEL));
        this.add(new LoginPanel(ComponentIDs.LOGIN_PANEL).setOutputMarkupId(false));
        
        ResourceReference ref = new PackageResourceReference(ImageAnchor.class, "header_with_logo_700xp.png");
        Image image = new Image(ComponentIDs.MAIN_IMAGE, ref);
        add(image);
        ClientSideImageMap imageMap = new ClientSideImageMap(ComponentIDs.MAIN_IMAGE_LINK_MAP, image);
        imageMap.addRectangleArea(homePageLink, 23, 27, 189, 121);
        this.add(imageMap);
        
        final int minWidth = 500;
        MusicLibrarySession session = MusicLibrarySession.get();
        
        final ModalWindow artistWindow = new ModalWindow(ComponentIDs.ADD_ARTIST_MODAL) {
            
            @Override
            public void show(AjaxRequestTarget target) {
                this.setContent(new ArtistFormPanel(this.getContentId()));
                super.show(target);
            }
        };
        this.add(artistWindow);
        artistWindow.setTitle(new StringResourceModel("ArtistFormPanel.title", this, null));
        artistWindow.setMinimalWidth(minWidth);
        artistWindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
        AjaxLink artistLink = new AjaxLink(ComponentIDs.ADD_ARTIST_MODAL_LINK) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                artistWindow.show(target);
            }

            @Override
            public void onEvent(IEvent<?> event) {
                if (artistWindow.isShown() && event.getPayload() instanceof FormSubmittedEvent) {
                    FormSubmittedEvent submitted = (FormSubmittedEvent) event.getPayload();
                    artistWindow.close(submitted.getTarget());
                }
            }
            
        };
        artistLink.setVisible(session.isAuthorized());
        this.add(artistLink);

        final ModalWindow genreWindow = new ModalWindow(ComponentIDs.ADD_GENRE_MODAL) {
            
            @Override
            public void show(AjaxRequestTarget target) {
                this.setContent(new GenreFormPanel(this.getContentId()));
                super.show(target);
            }
        };
        this.add(genreWindow);
        genreWindow.setTitle(new StringResourceModel("GenreFormPanel.title", this, null));
        genreWindow.setMinimalWidth(minWidth);
        genreWindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
        AjaxLink genreLink = new AjaxLink(ComponentIDs.ADD_GENRE_MODAL_LINK) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                genreWindow.show(target);
            }

            @Override
            public void onEvent(IEvent<?> event) {
                if (genreWindow.isShown() && event.getPayload() instanceof FormSubmittedEvent) {
                    FormSubmittedEvent submitted = (FormSubmittedEvent) event.getPayload();
                    genreWindow.close(submitted.getTarget());
                }
            }
            
        };
        genreLink.setVisible(session.isAuthorized());
        this.add(genreLink);
        

        final ModalWindow albumWindow = new ModalWindow(ComponentIDs.ADD_ALBUM_MODAL) {

            @Override
            public void show(AjaxRequestTarget target) {
                this.setContent(new AlbumFormPanel(this.getContentId()));
                super.show(target);
            }
        };
        this.add(albumWindow);
        albumWindow.setTitle(new StringResourceModel("AlbumFormPanel.title", this, null));
        albumWindow.setMinimalWidth(minWidth);
        albumWindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
        AjaxLink albumLink = new AjaxLink(ComponentIDs.ADD_ALBUM_MODAL_LINK) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                albumWindow.show(target);
            }

            @Override
            public void onEvent(IEvent<?> event) {
                if (albumWindow.isShown() && event.getPayload() instanceof FormSubmittedEvent) {
                    FormSubmittedEvent submitted = (FormSubmittedEvent) event.getPayload();
                    albumWindow.close(submitted.getTarget());
                }
            }
            
        };
        albumLink.setVisible(session.isAuthorized());
        this.add(albumLink);

        final ModalWindow songWindow = new ModalWindow(ComponentIDs.ADD_SONG_MODAL) {

            @Override
            public void show(AjaxRequestTarget target) {
                this.setContent(new SongFormPanel(this.getContentId()));
                super.show(target);
            }
        };
        this.add(songWindow);
        songWindow.setTitle(new StringResourceModel("SongFormPanel.title", this, null));
        songWindow.setMinimalWidth(minWidth);
        songWindow.setMinimalHeight(550);
        songWindow.setInitialHeight(550);
        songWindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
        AjaxLink songLink = new AjaxLink(ComponentIDs.ADD_SONG_MODAL_LINK) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                songWindow.show(target);
            }

            @Override
            public void onEvent(IEvent<?> event) {
                if (songWindow.isShown() && event.getPayload() instanceof FormSubmittedEvent) {
                    FormSubmittedEvent submitted = (FormSubmittedEvent) event.getPayload();
                    songWindow.close(submitted.getTarget());
                }
            }
            
        };
        songLink.setVisible(session.isAuthorized());
        this.add(songLink);
        
    }

    /** Identifiers of added components. */
    private static final class ComponentIDs {
        /** Link to home page. */
        private static final String HOME_PAGE_LINK = "homePageLink";
        /** Search panel on top of the page. */
        private static final String SEARCH_FORM_PANEL = "searchFormPanel";
        
        private static final String LOGIN_PANEL = "loginPanel";
        
        private static final String MAIN_IMAGE = "image";
        
        private static final String MAIN_IMAGE_LINK_MAP = "mainImageLinkMap";
        
        private static final String ADD_ARTIST_MODAL = "addArtistModal";
        private static final String ADD_ARTIST_MODAL_LINK = "addArtistModalLink";
        
        private static final String ADD_GENRE_MODAL = "addGenreModal";
        private static final String ADD_GENRE_MODAL_LINK = "addGenreModalLink";
        
        private static final String ADD_ALBUM_MODAL = "addAlbumModal";
        private static final String ADD_ALBUM_MODAL_LINK = "addAlbumModalLink";
        
        private static final String ADD_SONG_MODAL = "addSongModal";
        private static final String ADD_SONG_MODAL_LINK = "addSongModalLink";
    }
}